#include "global.h"
#include "write.h"
#include <random>
#include <queue>
#include <cmath>

//Strategy
#define MAX_CYCLE (16+1)
const int CYCLE=15;
extern bool shouldbusy[MAX_OBJECT_NUM];
extern int lstvis[MAX_OBJECT_NUM][MAX_OBJECT_SIZE];

#define MAX_POINT_NUM (20+1)
class Decider
{
protected:
	mt19937 mrand;
	double pred[3][MAX_VDISK_SIZE+1],pred_sum[3][MAX_VDISK_SIZE+1];
	double score[3][MAX_VDISK_SIZE+1],score_sum[3][MAX_VDISK_SIZE+1];

	//sum of [L,R)
	double getscore_sum(int L,int R,double *sum) const;
	void scoresum_prepare();
	void DiskScore_calc();
	double getsum(DiskPoint *points,int *st,int pointnum,int extradis,double val,const double sum[3][MAX_VDISK_SIZE+1]) const;
	double getans(DiskPoint *points,int *st,int pointnum) const;

public:
	Decider(){mrand=mt19937(19491001);}
	int GA(int d,int pointid);
	int simulateAnneal(int d,int pointid);
	// inline int decide(int d,int pointid){return GA(d,pointid);}
	inline int decide(int d,int pointid){return simulateAnneal(d,pointid);}
};



const double decayrate=0.995;
extern double powd[MAX_T+EXTRA_TIME];
extern int lstreq[MAX_OBJECT_NUM];
extern double readpred[MAX_OBJECT_NUM];



//Report
extern queue<int> busylist,donelist,Busy_intime[MAX_TIME_SLICING];
inline void bebusy(int r)
{
	if(!request[r].is_completed()&&!request[r].isbusy&&!object[request[r].object_id].is_delete)
		busylist.push(r),request[r].isbusy=1;
}


//Interaction Function
void Jump(DiskPoint &point,int x);
void Pass(DiskPoint &point,int &usedtok);
bool Read(int d,DiskPoint &point,int &usedtok);
void DoneReport();
void BusyReport();